#include "TaskQueue.h"

TaskQueue::TaskQueue(size_t capa)
    : _capacity(capa), _que(), _mtx(), _notEmpty(), _notFull(), _flag(true)
{
}

TaskQueue::~TaskQueue()
{
}

// 生产与消费
void TaskQueue::push(ElemType ptask)
{
    // 1、上锁
    unique_lock<mutex> ul(_mtx);
    // 2、判满
    while (full()) // 防止虚假唤醒
    {
        // 3、如果是满的，就直接睡眠
        _notFull.wait(ul);
    }
    // 4、如果不满，将数据value存起来
    _que.push(ptask);
    // 5、唤醒消费者
    _notEmpty.notify_one();
    // 6、解锁
}

ElemType TaskQueue::pop()
{
    // 1、上锁
    unique_lock<mutex> ul(_mtx);
    // 2、判空
    while (empty() && _flag) // while 防止虚假唤醒
    {
        // 3、如果是空的，就直接睡眠
        _notEmpty.wait(ul);
    }
    if (_flag)
    {
        // 4、如果不空，将数据value取出来
        ElemType value = _que.front();
        _que.pop();
        // 5、唤醒生产者
        _notFull.notify_one();
        // 6、解锁
        return value;
    }
    else
    {
        return nullptr;
    }
}
bool TaskQueue::empty() const
{
    return 0 == _que.size();
}

bool TaskQueue::full() const
{
    return _que.size() == _capacity;
}

int TaskQueue::size() const
{
    return _que.size();
}

void TaskQueue::weakup()
{
    _flag = false;
    _notEmpty.notify_all();
}
